import java.util.Arrays;
import java.util.Comparator;

public class YetAnotherHamiltonianPath {
	public int leastCost(final String[] labels) {
		int result = 0;
		for (String label : labels)
			result += 2 * label.length() * label.length();
		result -= labels[0].length() * labels[0].length() + labels[1].length() * labels[1].length();
		int common = commonSubstringLength(labels[0], labels[1]);
		int labelCount = labels.length;
		Integer[] order = new Integer[labelCount];
		for (int i = 0; i < labelCount; i++)
			order[i] = i;
		Arrays.sort(order, new Comparator<Integer>() {
			public int compare(Integer o1, Integer o2) {
				if (o1 == 0)
					return -1;
				if (o1 == 1)
					return 1;
				if (o2 == 0)
					return 1;
				if (o2 == 1)
					return -1;
				int common1First = commonSubstringLength(labels[o1], labels[0]);
				int common1Last = commonSubstringLength(labels[o1], labels[1]);
				int common2First = commonSubstringLength(labels[o2], labels[0]);
				int common2Last = commonSubstringLength(labels[o2], labels[1]);
				if (common1First >= common1Last && common2First < common2Last)
					return -1;
				if (common1First < common1Last && common2First >= common2Last)
					return 1;
				int common1 = Math.max(common1First, common1Last);
				int common2 = Math.max(common2First, common2Last);
				if (common1 == common2)
					return labels[o1].compareTo(labels[o2]);
				if (common1 == common1First)
					return common2 - common1;
				return common1 - common2;
			}
		});
		for (int i = 1; i < labelCount; i++) {
			int commonLength = commonSubstringLength(labels[order[i - 1]], labels[order[i]]);
			result -= commonLength * commonLength;
		}
		return result;
	}

	int commonSubstringLength(String first, String second) {
		for (int i = 0; ; i++) {
			if (first.length() == i || second.length() == i || first.charAt(i) != second.charAt(i))
				return i;
		}
	}

// BEGIN CUT HERE
   public static void main(String[] args) {
		if ( args.length == 0 ) {
			YetAnotherHamiltonianPathHarness.run_test(-1);
		} else {
			for ( int i=0; i<args.length; ++i )
				YetAnotherHamiltonianPathHarness.run_test(Integer.valueOf(args[i]));
		}
	}
// END CUT HERE
}

// BEGIN CUT HERE
class YetAnotherHamiltonianPathHarness {
	public static void run_test( int casenum ) {
		if ( casenum != -1 ) {
			if ( runTestCase( casenum ) == -1 )
				System.err.println("Illegal input! Test case " + casenum + " does not exist.");
			return;
		}
		
		int correct = 0, total = 0;
		for ( int i=0;; ++i ) {
			int x = runTestCase(i);
			if ( x == -1 ) {
				if ( i >= 100 ) break;
				continue;
			}
			correct += x;
			++total;
		}
		
		if ( total == 0 ) {
			System.err.println("No test cases run.");
		} else if ( correct < total ) {
			System.err.println("Some cases FAILED (passed " + correct + " of " + total + ").");
		} else {
			System.err.println("All " + total + " tests passed!");
		}
	}
	
	static boolean compareOutput(int expected, int result) { return expected == result; }
	static String formatResult(int res) {
		return String.format("%d", res);
	}
	
	static int verifyCase( int casenum, int expected, int received ) { 
		System.err.print("Example " + casenum + "... ");
		if ( compareOutput( expected, received ) ) {
			System.err.println("PASSED");
			return 1;
		} else {
			System.err.println("FAILED");
			System.err.println("    Expected: " + formatResult(expected)); 
			System.err.println("    Received: " + formatResult(received)); 
			return 0;
		}
	}

	static int runTestCase( int casenum ) {
		switch( casenum ) {
		case 0: {
			String[] label            = {"home", "school", "pub"} ;
			int expected__            = 70;

			return verifyCase( casenum, expected__, new YetAnotherHamiltonianPath().leastCost( label ) );
		}
		case 1: {
			String[] label            = {"school", "home", "pub", "stadium"};
			int expected__            = 167;

			return verifyCase( casenum, expected__, new YetAnotherHamiltonianPath().leastCost( label ) );
		}
		case 2: {
			String[] label            = {"abcd","aecgh","abef","aecd"};
			int expected__            = 91;

			return verifyCase( casenum, expected__, new YetAnotherHamiltonianPath().leastCost( label ) );
		}
		case 3: {
			String[] label            = {"canada", "cyprus", "croatia", "colombia", "chile", "china", "cameroon"};
			int expected__            = 509;

			return verifyCase( casenum, expected__, new YetAnotherHamiltonianPath().leastCost( label ) );
		}

		// custom cases

/*      case 4: {
			String[] label            = ;
			int expected__            = ;

			return verifyCase( casenum, expected__, new YetAnotherHamiltonianPath().leastCost( label ) );
		}*/
/*      case 5: {
			String[] label            = ;
			int expected__            = ;

			return verifyCase( casenum, expected__, new YetAnotherHamiltonianPath().leastCost( label ) );
		}*/
/*      case 6: {
			String[] label            = ;
			int expected__            = ;

			return verifyCase( casenum, expected__, new YetAnotherHamiltonianPath().leastCost( label ) );
		}*/
		default:
			return -1;
		}
	}
}

// END CUT HERE
